home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 112_01.zip / NROTXT.C < prev    next >
Text File  |  1993-06-19  |  10KB  |  637 lines

  1. /*
  2.  *    Text processing portion of NRO word processor
  3.  *
  4.  *    Stephen L. Browning
  5.  *    5723 North Parker Avenue
  6.  *    Indianapolis, Indiana 46220
  7.  */
  8.  
  9. #include "a:bdscio.h"
  10. #include "nro.h"
  11. #include "nrocom.c"
  12.  
  13. text(p)
  14. char *p;
  15. {
  16.     int i;
  17.     char wrdbuf[MAXLINE];
  18.  
  19.     if (*p == ' ' || *p == '\n' || *p == '\r') leadbl(p);
  20.     expesc(p,wrdbuf);
  21.     if (dc.ulval > 0) {
  22.         /*
  23.         *    Because of the way underlining is handled,
  24.         *    MAXLINE should be declared to be three times
  25.         *    larger than the longest expected input line
  26.         *    for underlining.  Since many of the character
  27.         *    buffers use this parameter, a lot of memory
  28.         *    can be allocated when it may not really be
  29.         *    needed.  A MAXLINE of 180 would allow about
  30.         *    60 characters in the output line to be
  31.         *    underlined (remember that only alphanumerics
  32.         *    get underlined - no spaces or punctuation).
  33.         */
  34.         underl(p,wrdbuf,MAXLINE);
  35.         --dc.ulval;
  36.     }
  37.     if (dc.cuval > 0) {
  38.         underl(p,wrdbuf,MAXLINE);
  39.         --dc.cuval;
  40.     }
  41.     if (dc.boval > 0) {
  42.         bold(p,wrdbuf,MAXLINE);
  43.         --dc.boval;
  44.     }
  45.     if (dc.ceval > 0) {
  46.         center(p);
  47.         put(p);
  48.         --dc.ceval;
  49.     }
  50.     else if (*p == '\r' || *p == '\n') put(p); /* all blank line */
  51.     else if (dc.fill == NO) put(p);        /* unfilled */
  52.     else {
  53.         while ((i = getwrd(p,wrdbuf)) > 0) {
  54.             putwrd(wrdbuf);
  55.             p += i;
  56.         }
  57.     }
  58. }
  59.  
  60.  
  61. /*
  62.  *    insert bold face text
  63.  */
  64.  
  65. bold(p0,p1,size)
  66. char *p0, *p1;
  67. int size;
  68. {
  69.     int i, j;
  70.  
  71.     j = 0;
  72.     for (i=0; (p0[i] != '\n') && (j < size-1); ++i) {
  73.         if (isalpha(p0[i]) || isdigit(p0[i])) {
  74.             p1[j++] = p0[i];
  75.             p1[j++] = '\b';
  76.         }
  77.         p1[j++] = p0[i];
  78.     }
  79.     p1[j++] = '\n';
  80.     p1[j] = EOS;
  81.     while (*p1 != EOS) *p0++ = *p1++;
  82.     *p0 = EOS;
  83. }
  84.  
  85.  
  86.  
  87.  
  88. /*
  89.  *    center a line by setting tival
  90.  */
  91.  
  92. center(p)
  93. char *p;
  94. {
  95.     dc.tival = max((dc.rmval + dc.tival - width(p)) >> 1,0);
  96. }
  97.  
  98.  
  99. /*
  100.  *    expand title buffer to include character string
  101.  */
  102.  
  103. expand(p0,c,s)
  104. char *p0;
  105. char c;
  106. char *s;
  107. {
  108.     char tmp[MAXLINE];
  109.     char *p, *q, *r;
  110.  
  111.     p = p0;
  112.     q = tmp;
  113.     while (*p != EOS) {
  114.         if (*p == c) {
  115.             r = s;
  116.             while (*r != EOS) *q++ = *r++;
  117.         }
  118.         else *q++ = *p;
  119.         ++p;
  120.     }
  121.     *q = EOS;
  122.     strcpy(p0,tmp);        /* copy it back */
  123. }
  124.  
  125.  
  126. /*
  127.  *    get field from title
  128.  */
  129.  
  130. char *getfield(p,q,delim)
  131. char *p, *q;
  132. char delim;
  133. {
  134.     while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS) {
  135.         *q++ = *p++;
  136.     }
  137.     *q = EOS;
  138.     if (*p == delim) ++p;
  139.     return(p);
  140. }
  141.  
  142.  
  143.  
  144. /*
  145.  *    get non-blank word from p0 into p1.
  146.  *    return number of characters processed.
  147.  */
  148.  
  149. getwrd(p0,p1)
  150. char *p0,*p1;
  151. {
  152.     int i;
  153.     char *p, c;
  154.  
  155.     i = 0;
  156.     while (*p0 == ' ' || *p0 == '\t') {
  157.         ++i;
  158.         ++p0;
  159.     }
  160.     p = p0;
  161.     while (*p0 != ' ' && *p0 != EOS && *p0 != '\t') {
  162.         if (*p0 == '\n' || *p0 == '\r') break;
  163.         *p1 = *p0++;
  164.         ++p1;
  165.         ++i;
  166.     }
  167.     c = *(p1-1);
  168.     if (c == '"') c = *(p1-2);
  169.     if (c == '?' || c == '!') {
  170.         *p1++ = ' ';
  171.         ++i;
  172.     }
  173.     if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower(*p))) {
  174.         *p1++ = ' ';
  175.         ++i;
  176.     }
  177.     *p1 = EOS;
  178.     return(i);
  179. }
  180.  
  181.  
  182. /*
  183.  *    convert integer to decimal ascii string
  184.  */
  185.  
  186. itoda(value,p,size)
  187. int value;
  188. char *p;
  189. int size;
  190. {
  191.     char c[7];
  192.     int i, j, k;
  193.     int aval;
  194.  
  195.     aval = abs(value);
  196.     c[0] = EOS;
  197.     i = 1;
  198.     do {
  199.         c[i++] = (aval % 10) + '0';
  200.         aval /= 10;
  201.     } while (aval > 0 && i <= size);
  202.     if (value < 0 && i <= size) c[i++] = '-';
  203.     for (j=0; j<i; ++j) *p++ = c[i-j-1];
  204.     return(i);
  205. }
  206.  
  207.  
  208. /*
  209.  *    center title text into print buffer
  210.  */
  211.  
  212. justcntr(p,q,limit)
  213. char *p, *q;
  214. int limit[];
  215. {
  216.     int len;
  217.  
  218.     len = width(p);
  219.     q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
  220.     while (*p != EOS) *q++ = *p++;
  221. }
  222.  
  223.  
  224.  
  225. /*
  226.  *    left justify title text into print buffer
  227.  */
  228.  
  229. justleft(p,q,limit)
  230. char *p, *q;
  231. int limit;
  232. {
  233.     q = &q[limit];
  234.     while (*p != EOS) *q++ = *p++;
  235. }
  236.  
  237.  
  238. /*
  239.  *    right justify title text into print buffer
  240.  */
  241.  
  242. justrite(p,q,limit)
  243. char *p, *q;
  244. int limit;
  245. {
  246.     int len;
  247.  
  248.     len = width(p);
  249.     q = &q[limit - len];
  250.     while (*p != EOS) *q++ = *p++;
  251. }
  252.  
  253.  
  254.  
  255.  
  256. /*
  257.  *    delete leading blanks, set tival
  258.  */
  259.  
  260. leadbl(p)
  261. char *p;
  262. {
  263.     int i,j;
  264.  
  265.     brk();
  266.     for (i=0; p[i] == ' '; ++i) ;
  267.     if (p[i] != '\n' && p[i] != '\r') dc.tival = i;
  268.     for (j=0; p[i] != EOS; ++j) p[j] = p[i++];
  269.     p[j] = EOS;
  270. }
  271.  
  272.  
  273.  
  274. /*
  275.  *    find minimum of two integer
  276.  */
  277.  
  278. min(v1,v2)
  279. int v1,v2;
  280. {
  281.     return((v1 < v2) ? v1 : v2);
  282. }
  283.  
  284.  
  285.  
  286. /*
  287.  *    find maximum of two integers
  288.  */
  289.  
  290. max(v1,v2)
  291. int v1,v2;
  292. {
  293.     return((v1 > v2) ? v1 : v2);
  294. }
  295.  
  296.  
  297.  
  298. /*
  299.  *    put out page footer
  300.  */
  301.  
  302. pfoot()
  303. {
  304.     if (dc.prflg == TRUE) {
  305.         skip(pg.m3val);
  306.         if (pg.m4val > 0) {
  307.             if ((pg.curpag % 2) == 0) {
  308.                 puttl(pg.efoot,pg.eflim,pg.curpag);
  309.             }
  310.             else {
  311.                 puttl(pg.ofoot,pg.oflim,pg.curpag);
  312.             }
  313.             skip(pg.m4val - 1);
  314.         }
  315.     }
  316. }
  317.  
  318.  
  319.  
  320. /*
  321.  *    put out page header
  322.  */
  323.  
  324. phead()
  325. {
  326.     pg.curpag = pg.newpag;
  327.     if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg) {
  328.         dc.prflg = TRUE;
  329.     }
  330.     else {
  331.         dc.prflg = FALSE;
  332.     }
  333.     ++pg.newpag;
  334.     if (dc.prflg == TRUE) {
  335.         if (pg.m1val > 0) {
  336.             skip(pg.m1val - 1);
  337.             if ((pg.curpag % 2) == 0) {
  338.                 puttl(pg.ehead,pg.ehlim,pg.curpag);
  339.             }
  340.             else {
  341.                 puttl(pg.ohead,pg.ohlim,pg.curpag);
  342.             }
  343.         }
  344.         skip(pg.m2val);
  345.     }
  346.     /*
  347.     *    initialize lineno for the next page
  348.     */
  349.     pg.lineno = pg.m1val + pg.m2val + 1;
  350. }
  351.  
  352.  
  353. /*
  354.  *    print character with test for printer
  355.  */
  356.  
  357. prchar(c,fp)
  358. char c;
  359. struct _buf *fp;
  360. {
  361.     if (co.lpr == TRUE) {
  362.         bdos(5,c);
  363.     }
  364.     else {
  365.         putc(c,fp);
  366.     }
  367. }
  368.  
  369.  
  370.  
  371.  
  372. /*
  373.  *    put out line with proper spacing and indenting
  374.  */
  375.  
  376. put(p)
  377. char *p;
  378. {
  379.     char os[MAXLINE];
  380.     int j;
  381.  
  382.     if (pg.lineno == 0 || pg.lineno > pg.bottom) {
  383.         phead();
  384.     }
  385.     if (dc.prflg == TRUE) {
  386.         if (!dc.bsflg) {
  387.             if (strkovr(p,os) == TRUE) {
  388.                 for (j=0; j<pg.offset; ++j) prchar(' ',pout);
  389.                 for (j=0; j<dc.tival; ++j) prchar(' ',pout);
  390.                 putlin(os,pout);
  391.             }
  392.         }
  393.         for (j=0; j<pg.offset; ++j) prchar(' ',pout);
  394.         for (j=0; j<dc.tival; ++j) prchar(' ',pout);
  395.         putlin(p,pout);
  396.     }
  397.     dc.tival = dc.inval;
  398.     skip(min(dc.lsval-1,pg.bottom-pg.lineno));
  399.     pg.lineno = pg.lineno + dc.lsval;
  400.     if (pg.lineno > pg.bottom) pfoot();
  401. }
  402.  
  403.  
  404. /*
  405.  *    output a null terminated string to the file
  406.  *    specified by pbuf.
  407.  */
  408.  
  409. putlin(p,pbuf)
  410. char *p;
  411. struct buf *pbuf;
  412. {
  413.     while (*p != EOS) prchar(*p++,pbuf);
  414. }
  415.  
  416.  
  417.  
  418. /*
  419.  *    put out title or footer
  420.  */
  421.  
  422. puttl(p,lim,pgno)
  423. char *p;
  424. int lim[];
  425. int pgno;
  426. {
  427.     int i;
  428.     char pn[8];
  429.     char t[MAXLINE];
  430.     char h[MAXLINE];
  431.     char delim;
  432.  
  433.     itoda(pgno,pn,6);
  434.     for (i=0; i<MAXLINE; ++i) h[i] = ' ';
  435.     delim = *p++;
  436.     p = getfield(p,t,delim);
  437.     expand(t,dc.pgchr,pn);
  438.     justleft(t,h,lim[LEFT]);
  439.     p = getfield(p,t,delim);
  440.     expand(t,dc.pgchr,pn);
  441.     justcntr(t,h,lim);
  442.     p = getfield(p,t,delim);
  443.     expand(t,dc.pgchr,pn);
  444.     justrite(t,h,lim[RIGHT]);
  445.     for (i=MAXLINE-4; h[i] == ' '; --i) h[i] = EOS;
  446.     h[++i] = '\n';
  447.     h[++i] = '\r';
  448.     h[++i] = EOS;
  449.     if (strlen(h) > 2) {
  450.         for (i=0; i<pg.offset; ++i) prchar(' ',pout);
  451.     }
  452.     putlin(h,pout);
  453. }
  454.  
  455.  
  456.  
  457. /*
  458.  *    put word in output buffer
  459.  */
  460.  
  461. putwrd(wrdbuf)
  462. char *wrdbuf;
  463. {
  464.     int w;
  465.     int last;
  466.     int llval;
  467.     char *p0, *p1;
  468.     int nextra;
  469.  
  470.     w = width(wrdbuf);
  471.     last = strlen(wrdbuf) + co.outp;
  472.     llval = dc.rmval - dc.tival;
  473.     if(((co.outp > 0) && ((co.outw + w) > llval)) || (last > MAXLINE)) {
  474.         last -= co.outp;
  475.         if(dc.juval == YES) {
  476.             nextra = llval - co.outw + 1;
  477.             /*
  478.             *    Check whether last word was end of
  479.             *    sentence and modify counts so that
  480.             *    it is right justified.
  481.             */
  482.             if (co.outbuf[co.outp-2] == ' ') {
  483.                 --co.outp;
  484.                 ++nextra;
  485.             }
  486.             spread(co.outbuf,co.outp-1,nextra,co.outwds);
  487.             if((nextra > 0) && (co.outwds > 1)) {
  488.                 co.outp += (nextra - 1);
  489.             }
  490.         }
  491.         brk();
  492.     }
  493.     p0 = wrdbuf;
  494.     p1 = co.outbuf + co.outp;
  495.     while(*p0 != EOS) *p1++ = *p0++;
  496.     co.outp = last;
  497.     co.outbuf[co.outp++] = ' ';
  498.     co.outw += w + 1;
  499.     ++co.outwds;
  500. }
  501.  
  502.  
  503. /*
  504.  *    skips the number of lines specified by n.
  505.  */
  506.  
  507. skip(n)
  508. int n;
  509. {
  510.     int i;
  511.  
  512.     if (dc.prflg == TRUE && n > 0) {
  513.         for(i=0; i<n; ++i) {
  514.             prchar('\n',pout);
  515.         }
  516.         prchar('\r',pout);
  517.     }
  518. }
  519.  
  520.  
  521.  
  522. /*
  523.  *    spread words to justify right margin
  524.  */
  525.  
  526. spread(p,outp,nextra,outwds)
  527. char p[];
  528. int outp,nextra,outwds;
  529. {
  530.     int i,j;
  531.     int nb,ne,nholes;
  532.  
  533.     if((nextra <= 0) || (outwds <= 1)) return;
  534.     dc.sprdir = ~dc.sprdir;
  535.     ne = nextra;
  536.     nholes = outwds - 1;    /* holes between words */
  537.     i = outp - 1;    /* last non-blank character */
  538.     j = min(MAXLINE-3,i+ne); /* leave room for CR, LF, EOS  */
  539.     while(i < j) {
  540.         p[j] = p[i];
  541.         if(p[i] == ' ') {
  542.             if(dc.sprdir == 0) nb = (ne - 1)/nholes + 1;
  543.             else nb = ne/nholes;
  544.             ne -= nb;
  545.             --nholes;
  546.             for(; nb>0; --nb) {
  547.                 --j;
  548.                 p[j] = ' ';
  549.             }
  550.         }
  551.         --i;
  552.         --j;
  553.     }
  554. }
  555.  
  556.  
  557.  
  558. /*
  559.  *    split overstrikes (backspaces) into seperate buffer
  560.  */
  561.  
  562. strkovr(p,q)
  563. char *p, *q;
  564. {
  565.     char *pp;
  566.     int bsflg;
  567.  
  568.     bsflg = FALSE;
  569.     pp = p;
  570.     while (*p != EOS) {
  571.         *q = ' ';
  572.         *pp = *p;
  573.         ++p;
  574.         if (*p == '\b') {
  575.             if (*pp >= ' ' && *pp <= '~') {
  576.                 bsflg = TRUE;
  577.                 *q = *pp;
  578.                 ++p;
  579.                 *pp = *p;
  580.                 ++p;
  581.             }
  582.         }
  583.         ++q;
  584.         ++pp;
  585.     }
  586.     *q++ = '\r';
  587.     *q = *pp = EOS;
  588.     return(bsflg);
  589. }
  590.  
  591.  
  592.  
  593. /*
  594.  *    underline a line
  595.  */
  596.  
  597. underl(p0,p1,size)
  598. char *p0,*p1;
  599. int size;
  600. {
  601.     int i,j;
  602.  
  603.     j = 0;
  604.     for (i=0; (p0[i] != '\n') && (j < size-1); ++i) {
  605.         if (p0[i] >= ' ' && p0[i] <= '~') {
  606.             if (isalpha(p0[i]) || isdigit(p0[i]) || dc.cuval > 0) {
  607.                 p1[j++] = '_';
  608.                 p1[j++] = '\b';
  609.             }
  610.         }
  611.         p1[j++] = p0[i];
  612.     }
  613.     p1[j++] = '\n';
  614.     p1[j] = EOS;
  615.     while (*p1 != EOS) *p0++ = *p1++;
  616.     *p0 = EOS;
  617. }
  618.  
  619.  
  620. /*
  621.  *    compute width of character string
  622.  */
  623.  
  624. width(s)
  625. char *s;
  626. {
  627.     int w;
  628.  
  629.     w = 0;
  630.     while (*s != EOS) {
  631.         if (*s == '\b') --w;
  632.         else if (*s != '\n' && *s != '\r') ++w;
  633.         ++s;
  634.     }
  635.     return(w);
  636. }
  637.